import React, {
  Fragment,
  useEffect,
  useContext,
  useState,
  useMemo,
  forwardRef,
  useRef,
  useCallback
} from "react";
import { Table, Form, Popconfirm, Input, Button } from "antd";
import EditableFormTableContext from "./EditableTableContext";
import "./EditableTableField.less";

const { Provider, Consumer } = EditableFormTableContext;

const EditableCell = props => {
  const {
    editing,
    dataIndex,
    title,
    record,
    children,
    inputType,
    ...restProps
  } = props;
  const { getFieldDecorator } = useContext(EditableFormTableContext);
  const getInput = () => {
    if (inputType === "text") {
      return <Input />;
    }
    return <Input />;
  };
  return (
    <td {...restProps}>
      {editing ? (
        <Form.Item style={{ margin: 0 }}>
          {getFieldDecorator(dataIndex, {
            rules: [
              {
                required: true,
                message: `请输入 ${title}!`
              }
            ],
            initialValue: record[dataIndex]
          })(getInput())}
        </Form.Item>
      ) : (
        children
      )}
    </td>
  );
};

const columns = [
  {
    title: "属性编码",
    dataIndex: "attributeCode",
    width: "35%",
    editable: true
  },
  {
    title: "属性值",
    dataIndex: "attributeValue",
    width: "35%",
    editable: true
  }
];

const ROW_KEY_PREFIX = "NEW-ROW";

const EditableTable = ({ value = [], onChange, form }, ref) => {
  const [editingId, setEditingId] = React.useState("");
  const [data, setData] = useState(value);
  const newRowKey = useRef(0);

  const isEditing = useCallback(record => record.id === editingId, [editingId]);

  const generateNewRow = useCallback(
    () => ({
      // eslint-disable-next-line no-plusplus
      id: `${ROW_KEY_PREFIX}-${newRowKey.current++}`,
      attributeCode: "",
      attributeValue: "",
      isDeleted: "N"
    }),
    [ROW_KEY_PREFIX, newRowKey]
  );

  useEffect(() => {
    // console.log('---------------------------');
    // console.log(data);
    // console.log(data.filter(item => item.id.startsWith(ROW_KEY_PREFIX) === false));
    onChange(data);
  }, [data]);

  useEffect(() => {
    setData(value);
    // console.log("setFields", value);
  }, [value]);

  const save = useCallback(
    (frm, key) => {
      frm.validateFields((error, row) => {
        if (error) {
          return;
        }
        const index = data.findIndex(item => key === item.id);
        if (index > -1) {
          const newData = data.map((item, i) => {
            if (i === index) {
              return { ...row, isDeleted: "N" };
            }
            return item;
          });
          setData(newData);
          setEditingId("");
        } else {
          setData([...data, row]);
          setEditingId("");
        }
      });
    },
    [data]
  );

  const remove = useCallback(
    key => {
      const index = data.findIndex(item => key === item.id);
      const newData = data.map((item, idx) => {
        if (idx === index) {
          return { ...item, isDeleted: "Y" };
        }
        return item;
      });
      setData(newData);
      setEditingId("");
    },
    [data]
  );

  const cancel = useCallback(frm => {
    frm.validateFields(error => {
      if (error) {
        return;
      }
      setEditingId("");
    });
  }, []);

  const edit = key => {
    setEditingId(key);
  };

  const columnWithOperation = useMemo(
    () =>
      [
        ...columns,
        {
          title: "操作",
          dataIndex: "operation",
          render: (text, record) => {
            const editable = isEditing(record);
            return editable ? (
              <span>
                <Consumer>
                  {frm => (
                    <Fragment>
                      <a
                        onClick={() => save(frm, record.id)}
                        style={{ marginRight: 8 }}
                      >
                        保存
                      </a>
                      <Popconfirm
                        title="取消编辑将丢失当前行的修改，确认操作？"
                        onConfirm={() => cancel(frm, record.id)}
                      >
                        <a>取消</a>
                      </Popconfirm>
                      &nbsp;&nbsp;
                      <a onClick={() => remove(record.id)}>删除</a>
                    </Fragment>
                  )}
                </Consumer>
              </span>
            ) : (
              <Fragment>
                <a disabled={editingId !== ""} onClick={() => edit(record.id)}>
                  编辑
                </a>
                &nbsp;&nbsp;
                <a
                  disabled={editingId !== ""}
                  onClick={() => remove(record.id)}
                >
                  删除
                </a>
              </Fragment>
            );
          }
        }
      ].map(col => {
        if (!col.editable) {
          return col;
        }
        return {
          ...col,
          onCell: record => ({
            record,
            inputType: "text",
            dataIndex: col.dataIndex,
            title: col.title,
            editing: isEditing(record)
          })
        };
      }),
    [columns, isEditing, save, edit, remove, cancel]
  );

  return (
    <Provider value={form}>
      <Button
        onClick={() => {
          const newRow = generateNewRow();
          setData(state => [...state, newRow]);
          setEditingId(newRow.id);
        }}
        disabled={!!editingId}
      >
        添加配置属性
      </Button>
      <Table
        ref={ref}
        components={{
          body: {
            cell: EditableCell
          }
        }}
        bordered
        dataSource={data.filter(item => item.isDeleted === "N")}
        columns={columnWithOperation}
        rowClassName="editable-row"
        pagination={false}
      />
    </Provider>
  );
};

const EditableTableField = Form.create()(forwardRef(EditableTable));

export default EditableTableField;
